package com.luckyframe.project.jmeter.jmeterTestPlan.domain;

import com.luckyframe.project.jmeter.jmeterTestPlan.controller.JmeterTestPlanController;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 多个测试用例集合
 */
public class PlanCaseTaskGroup {

    private static final Logger logger = LoggerFactory.getLogger(JmeterTestPlanController.class);

    private volatile boolean lastHasFinished = true;

    private Object lock = new Object();

    //thread that execute tasks
    private ThreadPoolExecutor executor;

    private Throwable ex;

    private List<PlanCaseTask> planCaseTasks;

    private volatile boolean hasFailedCase = false;


    public ThreadPoolExecutor getExecutor() {
        return executor;
    }

    public void setExecutor(ThreadPoolExecutor executor) {
        this.executor = executor;
    }

    public List<PlanCaseTask> getPlanCaseTasks() {
        return planCaseTasks;
    }

    public void setPlanCaseTasks(List<PlanCaseTask> planCaseTasks) {
        this.planCaseTasks = planCaseTasks;
    }


    /**
     * 任务完成
     */
    public void caseFinished() {

        lastHasFinished = true;
        synchronized (lock) {
            lock.notifyAll();
        }
    }

    public void caseFailed(Throwable e) {

        lastHasFinished = true;
        hasFailedCase = true;
        this.ex=e;

        synchronized (lock) {
            lock.notifyAll();
        }
    }


    public void run() {

        if (CollectionUtils.isEmpty(planCaseTasks)) {
            return;
        }

        outer:
        for (PlanCaseTask planCaseTask : planCaseTasks) {

            synchronized (lock) {
                try {
                    while (!lastHasFinished && !Thread.interrupted()) {

                        logger.info("plan {} case {} wait @{}", planCaseTask.getPlan().getName(), planCaseTask.getTestCase().getCaseName(), Integer.toHexString(lock.hashCode()));

                        lock.wait();

                        if (hasFailedCase || ex!=null) {
                            break outer;
                        }

                        logger.info("plan {} case {} wait finished", planCaseTask.getPlan().getName(), planCaseTask.getTestCase().getCaseName(), lastHasFinished);
                    }

                } catch (InterruptedException e) {
                    logger.info("InterruptedException");
                    Thread.currentThread().interrupt();
                }
            }

            lastHasFinished = false;
            planCaseTask.run(this);
        }
    }

}
